Bellman-Ford 演算法是一種用於解決最短路徑問題的演算法,可以處理包含負權重邊的圖。
演算法
Bellman-Ford 演算法通過不斷嘗試更新節點之間的最短距離,來找到從一個指定的源節點到圖中所有其他節點的最短路徑。
如果存在負權環,則演算法會檢測到它們。這個演算法的時間複雜度為 ,其中 
 是節點數,
 是邊數。

// Bellman Ford Algorithm in Kotlin
class BellmanFord {
    fun bellmanFord(graph: Array<IntArray>, V: Int, E: Int, src: Int) {
        // Initialize distance of all vertices as infinite.
        val dis = IntArray(V)
        for (i in 0 until V) dis[i] = Int.MAX_VALUE
        // initialize distance of source as 0
        dis[src] = 0
        // Relax all edges |V| - 1 times. A simple shortest
        // path from src to any other vertex can have at-most |V| - 1 edges
        for (i in 0 until V - 1) {
            for (j in 0 until E) {
                if (dis[graph[j][0]] != Int.MAX_VALUE && dis[graph[j][0]] + graph[j][2] < dis[graph[j][1]])
                    dis[graph[j][1]] = dis[graph[j][0]] + graph[j][2]
            }
        }
        // check for negative-weight cycles.
        for (i in 0 until E) {
            val x = graph[i][0]
            val y = graph[i][1]
            val weight = graph[i][2]
            if (dis[x] != Int.MAX_VALUE && dis[x] + weight < dis[y])
                println("Graph contains negative weight cycle")
        }
        println("Vertex Distance from Source")
        for (i in 0 until V) println("$i\t\t${dis[i]}")
    }
}
// main function
fun main(args: Array<String>) {
    val V = 5 // Number of vertices in graph
    val E = 8 // Number of edges in graph
    // Every edge has three values (u, v, w) where
    // the edge is from vertex u to v. And weight
    // of the edge is w.
    val graph = arrayOf(
        intArrayOf(0, 1, -1),
        intArrayOf(0, 2, 4),
        intArrayOf(1, 2, 3),
        intArrayOf(1, 3, 2),
        intArrayOf(1, 4, 2),
        intArrayOf(3, 2, 5),
        intArrayOf(3, 1, 1),
        intArrayOf(4, 3, -3)
    )
    val bellmanFord = BellmanFord()
    bellmanFord.bellmanFord(graph, V, E, 0)
}
Floyd-Warshall 演算法是一種用於解決所有節點對之間最短路徑問題的演算法。
它適用於有向圖或帶權有向圖,其中每條邊都有一個非負權重。
演算法
Floyd-Warshall 演算法的時間複雜度是,其中
是節點的數量。
優點是它可以處理包含負權邊的圖,並且它能夠找到所有節點對之間的最短路徑,而不僅僅是一對節點之間的最短路徑。
然而,對於大型圖,它的運行時間可能會變得很長。

// Floyd-Warshall Algorithm in Kotlin
// INF 
val INF = 99999
class FloydWarshall {
    // Number of vertices in the graph
    private val V = 4
    // Define infinity as the large enough value. This value will be
    // used for vertices not connected to each other
    private val INF = 99999
    // Solves the all-pairs shortest path problem using Floyd Warshall algorithm
    fun floydWarshall(graph: Array<IntArray>) {
        /* dist[][] will be the output matrix that will finally
        have the shortest distances between every pair of vertices */
        val dist = Array(V) { IntArray(V) }
        var i: Int
        var j: Int
        var k: Int
        /* Initialize the solution matrix same as input graph matrix.
        Or we can say the initial values of shortest distances
        are based on shortest paths considering no intermediate
        vertex. */
        i = 0
        while (i < V) {
            j = 0
            while (j < V) {
                dist[i][j] = graph[i][j]
                j++
            }
            i++
        }
        /* Add all vertices one by one to the set of intermediate
        vertices.
        ---> Before start of an iteration, we have shortest
        distances between all pairs of vertices such that
        the shortest distances consider only the vertices in
        set {0, 1, 2, .. k-1} as intermediate vertices.
        ----> After the end of an iteration, vertex no. k is
        added to the set of intermediate vertices and the
        set becomes {0, 1, 2, .. k} */
        k = 0
        while (k < V) {
            // Pick all vertices as source one by one
            i = 0
            while (i < V) {
                // Pick all vertices as destination for the
                // above picked source
                j = 0
                while (j < V) {
                    // If vertex k is on the shortest path from
                    // i to j, then update the value of dist[i][j]
                    if (dist[i][k] + dist[k][j] < dist[i][j])
                        dist[i][j] = dist[i][k] + dist[k][j]
                    j++
                }
                i++
            }
            k++
        }
        // Print the shortest distance matrix
        printSolution(dist)
    }
    /* A utility function to print solution */
    fun printSolution(dist: Array<IntArray>) {
        println("The following matrix shows the shortest " + "distances between every pair of vertices")
        var i = 0
        while (i < V) {
            var j = 0
            while (j < V) {
                if (dist[i][j] == INF)
                    print("%7s".format("INF"))
                else
                    print("%7d".format(dist[i][j]))
                j++
            }
            println()
            i++
        }
    }
}
// main function
fun main(args: Array<String>) {
    /* Let us create the following weighted graph
            10
    (0)------->(3)
        |     /|\
    5 |     |
        |     | 1
    \|/     |
    (1)------->(2)
            3     */
    val graph = arrayOf(intArrayOf(0, 5, INF, 10),
            intArrayOf(INF, 0, 3, INF),
            intArrayOf(INF, INF, 0, 1),
            intArrayOf(INF, INF, INF, 0))
    val a = FloydWarshall()
    // Print the solution
    a.floydWarshall(graph)
}
所有 Code 可以在 Github 找到 ~
明天會接著介紹 Prim's Algorithm 和 Kruskal's Algorithm
![]()